/**
 * 
 */
package org.hitlabnz.sensor_fusion_demo.orientationProvider;

import java.util.ArrayList;
import java.util.List;

import org.hitlabnz.sensor_fusion_demo.representation.MatrixF4x4;
import org.hitlabnz.sensor_fusion_demo.representation.Quaternion;

import android.hardware.Sensor;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

/**
 *实现此接口的类提供设备的方向
 *通过直接访问硬件，使用Android传感器融合或融合
 *传感器本身。
 *
 *方向可以提供为旋转矩阵或四元数。
 *
 *@作者Alexander Pacha
 *
 */
public abstract class OrientationProvider implements SensorEventListener {
    /**
     *同步令牌，用于从传感器管理器和同步对传感器数据的读/写
     *融合算法
     */
    protected final Object synchronizationToken = new Object();

    /**
     *此提供程序使用的传感器列表
     */
    protected List<Sensor> sensorList = new ArrayList<Sensor>();

    /**
     *保持当前旋转的矩阵
     */
    protected final MatrixF4x4 currentOrientationRotationMatrix;

    /**
     *保持当前旋转的四元数
     */
    protected final Quaternion currentOrientationQuaternion;

    /**
     *用于访问android传感器的传感器管理器
     */
    protected SensorManager sensorManager;

    /**
     *初始化新的OrientationProvider
     *
     *@param sensorManager
     *安卓传感器管理器
     */
    public OrientationProvider(SensorManager sensorManager) {
        this.sensorManager = sensorManager;

        // Initialise with identity
        currentOrientationRotationMatrix = new MatrixF4x4();

        // Initialise with identity
        currentOrientationQuaternion = new Quaternion();
    }

    /**
     *启动传感器融合（例如，在恢复活动时）
     */
    public void start() {
        // enable our sensor when the activity is resumed, ask for
        // 10 ms updates.
        for (Sensor sensor : sensorList) {
            // enable our sensors when the activity is resumed, ask for
            // 20 ms updates (Sensor_delay_game)
            sensorManager.registerListener(this, sensor,
                    SensorManager.SENSOR_DELAY_GAME);
        }
    }

    /**
     * Stops the sensor fusion (e.g. when pausing/suspending the activity)
     */
    public void stop() {
        // make sure to turn our sensors off when the activity is paused
        for (Sensor sensor : sensorList) {
            sensorManager.unregisterListener(this, sensor);
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Not doing anything
    }
    /**
     *以旋转矩阵格式（4x4矩阵）获取设备的当前旋转
     */
    public void getRotationMatrix(MatrixF4x4 matrix) {
        synchronized (synchronizationToken) {
            matrix.set(currentOrientationRotationMatrix);
        }
    }

    /**
     *以四元数格式（vector4f）获取设备的当前旋转
     */
    public void getQuaternion(Quaternion quaternion) {
        synchronized (synchronizationToken) {
            quaternion.set(currentOrientationQuaternion);
        }
    }

    /**
     *获取设备在Euler角度中的当前旋转
     */
    public void getEulerAngles(float angles[]) {
        synchronized (synchronizationToken) {
            SensorManager.getOrientation(currentOrientationRotationMatrix.matrix, angles);
        }
    }
}
